#include "StdAfx.h"
#include "wsCallJS.h"

void wsCallJS::runJS(CDHtmlDialog* dlg, OLECHAR* funcName)
{
	IHTMLDocument2* pHTMLDoc;
	dlg->GetDHtmlDocument(&pHTMLDoc);
	
	IDispatch* pScript = NULL;
	pHTMLDoc->get_Script(&pScript);

	OLECHAR* sMethod = funcName;
	DISPID idSave;
	HRESULT hr = pScript->GetIDsOfNames(IID_NULL, &sMethod, 1, LOCALE_SYSTEM_DEFAULT, &idSave);

	if( SUCCEEDED(hr) )
	{
		DISPPARAMS dpNoArgs = {NULL, NULL, 0, 0};
		hr = pScript->Invoke(idSave, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &dpNoArgs, NULL, NULL, NULL);
	}

	pScript->Release();
	pHTMLDoc->Release();
}

wsCallJS::wsCallJS()
	:script(NULL)
{
}

wsCallJS::~wsCallJS()
{
	if (script)
		script->Release();
}

void wsCallJS::init(CDHtmlDialog* dlg)
{
	IHTMLDocument2* pHTMLDoc;
	dlg->GetDHtmlDocument(&pHTMLDoc);
	
	pHTMLDoc->get_Script(&script);
	pHTMLDoc->Release();
}

bool wsCallJS::call(const CString strFunc, const CStringArray& paramArray, CComVariant *vaReturn)
{
	ATLASSERT(script != NULL);
	CComPtr<IDispatch> spScript = script;
 
	CComBSTR bstrMember(strFunc);
	DISPID dispid = NULL;
	HRESULT hr = spScript->GetIDsOfNames(IID_NULL,&bstrMember,1,LOCALE_SYSTEM_DEFAULT,&dispid);
	if(FAILED(hr))
	{
		//ShowError(GetSystemErrorMessage(hr));
		return false;
	}
 
	const int arraySize = paramArray.GetSize();
 
	DISPPARAMS dispparams;
	memset(&dispparams, 0, sizeof dispparams);
	dispparams.cArgs = arraySize;
	dispparams.rgvarg = new VARIANT[dispparams.cArgs];
 
	for( int i = 0; i < arraySize; i++)
	{
		CComBSTR bstr = paramArray.GetAt(arraySize - 1 - i); // back reading
		bstr.CopyTo(&dispparams.rgvarg[i].bstrVal);
		dispparams.rgvarg[i].vt = VT_BSTR;
	}
	dispparams.cNamedArgs = 0;
 
	EXCEPINFO excepInfo;
	memset(&excepInfo, 0, sizeof excepInfo);
	CComVariant vaResult;
	UINT nArgErr = (UINT)-1;  // initialize to invalid arg

	hr = spScript->Invoke(dispid,IID_NULL,0,
		DISPATCH_METHOD,&dispparams,&vaResult,&excepInfo,&nArgErr);
 
	delete [] dispparams.rgvarg;
	if(FAILED(hr))
	{
		//ShowError(GetSystemErrorMessage(hr));
		return false;
	}
 
	if(vaReturn)
	{
		*vaReturn = vaResult;			
	}

	return true;
}